package com.junjiao.util.java.servlet;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.junjiao.util.web.ParamUtil;

/**
 * @description: 二维码、条形码工具类 zxing 2.2<br>
 * @author:jiaojun
 * @email:junjiao.j@gmail.com
 * @project:junjiao util
 * @version:v0.2
 * @date:2013-9-11
 */
public class QRCodeServlet extends HttpServlet {
    /**
     * @description: 二维码编码 <br>
     * @author:jiaojun
     * @param contents
     *            欲编码内容,必填
     * @param width
     *            生成二维码图片宽度,默认200
     * @param height
     *            生成二维码图片高度,默认200
     *  example：http://www.51auto.com/QRCode?width=160&height=120&content=http://m.51auto.com/info.html?info_id=734561
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	response.setHeader("Pragma", "No-cache");
	response.setHeader("Cache-Control", "no-cache");
	response.setDateHeader("Expires", 1570694081590329344L);
	response.setContentType("image/png");
	response.setCharacterEncoding("GBK");
	ServletOutputStream out = response.getOutputStream();
	String contents = ParamUtil.getString(request, "content","");
	if("".equals(contents)){
	    out.print("QRCodeServlet parameter content is empty!!");
	    out.flush();
	    out.close();
	    throw new RuntimeException("QRCodeServlet parameter content is empty!!");
	}
	int width = ParamUtil.getInt(request, "width", 200);
	int height = ParamUtil.getInt(request, "height", 200);

	Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
	/**
	 * 容错率共四档:
		L     7%
		M    15%
		Q     25%
		H     30%
	 */
	hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
	/**
	 * 指定编码格式:特别声明此处的编码使用小写如utf-8 gbk
	 * 使用“UTF-8”，会在文本编码前添加一段ECI(扩充解释Extended Channel Interpretation)编码，就是这段编码导致手机不能解析。
	 * 如果使用小写"utf-8"会使这个ECI判断失效而不影响内容编码方式。
	 * 至于详细的ECI解释，可以看《QRCode 编码解码标准》
	 */
	hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
	// 指定空白边框大小
	hints.put(EncodeHintType.MARGIN, 1); 
	try {
	    BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,
		    BarcodeFormat.QR_CODE, width, height, hints);
	    MatrixToImageWriter.writeToStream(bitMatrix, "png", out);
	} catch (Exception e) {
	    e.printStackTrace();
	}finally{
	    out.flush();
	    out.close();
	}
    }
}
